package com.pureut.quality.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pureut.common.core.exception.GlobalException;
import com.pureut.common.core.utils.StringUtils;
import com.pureut.common.datascope.annotation.DataScope;
import com.pureut.common.security.utils.DictUtils;
import com.pureut.common.security.utils.SecurityUtils;
import com.pureut.quality.domain.QualityInspection;
import com.pureut.quality.domain.dto.QualityInspectionDto;
import com.pureut.quality.domain.vo.QualityInspectionVo;
import com.pureut.quality.export.QualityInspectionExport;
import com.pureut.quality.mapper.QualityInspectionMapper;
import com.pureut.quality.service.IQualityInspectionService;
import com.pureut.quality.service.PublicProjectService;
import com.pureut.system.api.FeignService;
import com.pureut.system.api.domain.SysDictData;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description 检验项目实现类
 * @Param
 * @Date 23-02-01
 * @Author hl
 **/
@Service
public class QualityInspectionServiceImpl extends ServiceImpl<QualityInspectionMapper, QualityInspection> implements IQualityInspectionService {

    @Resource
    private QualityInspectionMapper qualityInspectionMapper;

    @Resource
    FeignService feignService;

    @Resource
    PublicProjectService publicProjectService;

    /**
     * 查询检验项目
     *
     * @param qualityInspectionVo 检验项目接受类
     * @return list QualityInspectionDto
     */
    @Override
    @DataScope(deptAlias = "d")
    public List<QualityInspectionDto> selectInspectionList(QualityInspectionVo qualityInspectionVo) {
        List<QualityInspectionDto> qualityInspectionDtoList = qualityInspectionMapper.selectInspectionList(qualityInspectionVo);

        //检测阶别
        List<SysDictData> rankArray = DictUtils.getDictCache("item_rank");
        Map<String, String> rankMap = rankArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //物料类别
        List<SysDictData> materialCategoryArray = DictUtils.getDictCache("quality_category");
        Map<String, String> materialCategoryMap = materialCategoryArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //管控方式
        List<SysDictData> controlModeArray = DictUtils.getDictCache("quality_item_control_mode");
        Map<String, String> controlModeMap = controlModeArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        for (QualityInspectionDto entity : qualityInspectionDtoList) {
            //检测阶别
            entity.setItemRankDict(rankMap.get(entity.getItemRank()));
            //物料类别
            entity.setMaterialTypeDict(materialCategoryMap.get(entity.getMaterialType()));
            //管控方式
            entity.setItemControlModeDict(controlModeMap.get(entity.getItemControlMode()));
        }
        return qualityInspectionDtoList;
    }

    /**
     * 新增检验项目
     *
     * @param qualityInspectionVo 检验项目接受类
     * @return int 1 成功 2 失败
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean insertInspection(QualityInspectionVo qualityInspectionVo) throws Exception {
        QualityInspection qualityInspection = new QualityInspection();
        String authorityCoding = feignService.getAuthorityCoding("quality:verifyconfig:testitem:list");
        if (authorityCoding == null) {
            throw new GlobalException("该单据未进行配置，无法生成单据编码");
        }
        qualityInspection.setItemCode(authorityCoding)
                .setItemName(qualityInspectionVo.getItemName())
                .setItemRank(qualityInspectionVo.getItemRank())
                .setMaterialType(qualityInspectionVo.getMaterialType())
                .setItemControlMode(qualityInspectionVo.getItemControlMode())
                .setItemLowerLimit(qualityInspectionVo.getItemLowerLimit())
                .setItemUpperLimit(qualityInspectionVo.getItemUpperLimit())
                .setItemUnit(qualityInspectionVo.getItemUnit())
                .setItemSampleNumber(qualityInspectionVo.getItemSampleNumber())
                .setItemDetectionMode(qualityInspectionVo.getItemDetectionMode())
                .setItemCheckContent(qualityInspectionVo.getItemCheckContent())
                .setIsAverage(qualityInspectionVo.getIsAverage())
                .setCreateTime(new Date())
                .setDeptId(SecurityUtils.getDeptId());
        return save(qualityInspection);
    }

    /**
     * 批量删除检验项目
     *
     * @param itemId id
     * @return int 1 成功 2 失败
     */
    @Override
    public int deleteInspectionById(String itemId) {
        String[] itemIdS = itemId.split(",");
        return qualityInspectionMapper.deleteInspectionById(itemIdS);
    }

    /**
     * 根据编号获取详细信息
     *
     * @param itemId id
     * @return QualityInspectionDto 检测项目返回类
     */
    @Override
    public QualityInspectionDto selectInspectionById(long itemId) {
        QualityInspectionVo vo = new QualityInspectionVo();
        vo.setItemId(itemId);
        List<QualityInspectionDto> list = qualityInspectionMapper.selectInspectionList(vo);
        //检测阶别
        List<SysDictData> rankArray = DictUtils.getDictCache("item_rank");
        Map<String, String> rankMap = rankArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //物料类别
        List<SysDictData> materialCategoryArray = DictUtils.getDictCache("quality_category");
        Map<String, String> materialCategoryMap = materialCategoryArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //管控方式
        List<SysDictData> controlModeArray = DictUtils.getDictCache("quality_item_control_mode");
        Map<String, String> controlModeMap = controlModeArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        QualityInspectionDto qualityInspectionDto = list.get(0);
        //管控方式
        qualityInspectionDto.setItemControlModeDict(controlModeMap.get(qualityInspectionDto.getItemControlMode()));
        //检测阶别
        qualityInspectionDto.setItemRankDict(rankMap.get(qualityInspectionDto.getItemRank()));
        //物料类别
        qualityInspectionDto.setMaterialTypeDict(materialCategoryMap.get(qualityInspectionDto.getMaterialType()));
        return qualityInspectionDto;
    }

    /**
     * 修改检测项目
     *
     * @param qualityInspectionVo 检测项目接受类
     * @return int 1 成功 0 失败
     */
    @Override
    public boolean updateInspectionEdit(QualityInspectionVo qualityInspectionVo) {
        QualityInspection qualityInspection = getById(qualityInspectionVo.getItemId());
        qualityInspection.setItemName(qualityInspectionVo.getItemName())
                .setItemRank(qualityInspectionVo.getItemRank())
                .setMaterialType(qualityInspectionVo.getMaterialType())
                .setItemControlMode(qualityInspectionVo.getItemControlMode())
                .setItemLowerLimit(qualityInspectionVo.getItemLowerLimit())
                .setItemUpperLimit(qualityInspectionVo.getItemUpperLimit())
                .setItemUnit(qualityInspectionVo.getItemUnit())
                .setItemSampleNumber(qualityInspectionVo.getItemSampleNumber())
                .setItemDetectionMode(qualityInspectionVo.getItemDetectionMode())
                .setItemCheckContent(qualityInspectionVo.getItemCheckContent())
                .setIsAverage(qualityInspectionVo.getIsAverage());
        return updateById(qualityInspection);
    }


    /**
     * 导入
     *
     * @param coCustomer
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String importMouldData(List<QualityInspectionExport> coCustomer) {
        if (StringUtils.isNull(coCustomer) || coCustomer.size() == 0) {
            throw new GlobalException("导入检验项目信息不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        //检测阶别
        List<SysDictData> rankArray = DictUtils.getDictCache("item_rank");
        Map<String, String> rankMap = rankArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //物料类别
        List<SysDictData> materialCategoryArray = DictUtils.getDictCache("quality_category");
        Map<String, String> materialCategoryMap = materialCategoryArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //管控方式
        List<SysDictData> controlModeArray = DictUtils.getDictCache("quality_item_control_mode");
        Map<String, String> controlModeMap = controlModeArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        String regularExpression = "(^[+-]?[0-9]+)|(^[-+]?[0-9]\\.[0-9]*[1-9]$)|(^[-+]?[1-9]+[0-9]*\\.[0-9]*[1-9]$)";

        for (QualityInspectionExport mouldModelExport : coCustomer) {
            QualityInspection qualityInspection = new QualityInspection();
            try {
                //获取供应商编码
                String authorityCoding = feignService.getAuthorityCoding("quality:verifyconfig:testitem:list");
                if (authorityCoding == null) {
                    throw new GlobalException("该单据未进行配置，无法生成单据编码");
                }
                // 赋值
                qualityInspection.setItemCode(authorityCoding)
                        .setItemName(mouldModelExport.getItemName());
                //阶别
                for (Map.Entry<String, String> entry : rankMap.entrySet()) {
                    if (entry.getValue().equals(mouldModelExport.getItemRank())) {
                        qualityInspection.setItemRank(Integer.parseInt(entry.getKey()));
                        break;
                    }
                }
                //类别
                for (Map.Entry<String, String> entry : materialCategoryMap.entrySet()) {
                    if (entry.getValue().equals(mouldModelExport.getMaterialType())) {
                        qualityInspection.setMaterialType(Integer.parseInt(entry.getKey()));
                        break;
                    }
                }
                //管控方式
                for (Map.Entry<String, String> entry : controlModeMap.entrySet()) {
                    if (entry.getValue().equals(mouldModelExport.getItemControlMode())) {
                        qualityInspection.setItemControlMode(Integer.parseInt(entry.getKey()));
                        //如果是范围值
                        if ("1".equals(entry.getKey())) {
                            String itemUpperLimit = mouldModelExport.getItemUpperLimit();
                            String itemLowerLimit = mouldModelExport.getItemLowerLimit();

                            boolean matches = itemUpperLimit.matches(regularExpression);
                            boolean matches1 = itemLowerLimit.matches(regularExpression);
                            //下限值必须小于上限值,且不能为汉字和特殊符号，只能为数字
                            double up = Double.parseDouble(itemUpperLimit);
                            double down = Double.parseDouble(itemLowerLimit);
                            if (up > down && matches && matches1) {
                                qualityInspection.setItemLowerLimit(mouldModelExport.getItemLowerLimit())
                                        .setItemUpperLimit(mouldModelExport.getItemUpperLimit());
                            } else {
                                throw new GlobalException("上限值和下限值填写不正确，请核实");
                            }
                        } else if ("2".equals(entry.getKey())) {
                            //如果是固定值
                            if (mouldModelExport.getItemUpperLimit() != null) {
                                boolean matches = mouldModelExport.getItemUpperLimit().matches(regularExpression);
                                if (matches) {
                                    qualityInspection.setItemLowerLimit("--")
                                            .setItemUpperLimit(mouldModelExport.getItemUpperLimit());
                                }
                            } else {
                                throw new GlobalException("固定值时，上限值不能为空");
                            }
                        } else {
                            //状态值
                            qualityInspection.setItemLowerLimit("--")
                                    .setItemUpperLimit("--");
                        }
                        break;
                    }
                }
                qualityInspection.setItemUnit(mouldModelExport.getItemUnit())
                        .setItemSampleNumber(Integer.parseInt(mouldModelExport.getItemSampleNumber()))
                        .setItemDetectionMode(mouldModelExport.getItemDetectionMode())
                        .setItemCheckContent(mouldModelExport.getItemCheckContent());
                if ("开".equals(mouldModelExport.getIsAverage()) && !"3".equals(mouldModelExport.getItemControlMode())) {
                    qualityInspection.setIsAverage(1);
                } else {
                    qualityInspection.setIsAverage(2);
                }

                qualityInspection.setCreateTime(new Date())
                        .setDeptId(SecurityUtils.getDeptId());

                save(qualityInspection);

                successNum++;
                successMsg.append(successNum + "、检验项目信息 " + mouldModelExport.getItemName() + " 导入成功");

            } catch (Exception e) {
                failureNum++;
                String msg = failureNum + "、检验项目 " + mouldModelExport.getItemName() + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
                failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
                throw new GlobalException(failureMsg.toString());
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new GlobalException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }

        return successMsg.toString();
    }
}
